home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / VGX / blob / blob.c next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.4 KB  |  661 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <gl.h>
  18. #include <device.h>
  19. #include <math.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23.  
  24. #include "vect.h"
  25.  
  26. #define USETMESH
  27.  
  28. #define SPHERE 15
  29. #define SPRINGS 28
  30. #define VERTICES 8
  31.  
  32. #define GRID    3
  33.  
  34. #define GRIDXSIZE ((GRID)*2*4*4)
  35.  
  36.  
  37.  
  38. #define Pack(r,g,b,a) ((int)(r) | ((int)(g) << 8) | ((int)(b) << 16) | ((int)(a) << 24))
  39.  
  40. float    vel[VERTICES][3], vert[VERTICES][3], tot_force[VERTICES][3], 
  41.     sdist[SPRINGS], sdist_last[SPRINGS],
  42.     eye_ball[3],
  43.     damp, stiff, mtime, mass, gravity, floor_damp, fric, blur,
  44.     floor_z, ceiling_z;
  45.  
  46. int    sv1[SPRINGS], sv2[SPRINGS];
  47.  
  48. static  winxsize=0, winysize=0;
  49.  
  50.  
  51. float    ident_mat[4][4] =  { { 1, 0, 0, 0 },
  52.                 { 0, 1, 0, 0 },
  53.                 { 0, 0, 1, 0 },
  54.                 { 0, 0, 0, 1 } };
  55.  
  56. int    face[6][4] = { {0, 1, 5, 4},
  57.                {3, 7, 6, 2},
  58.                {3, 0, 4, 7},
  59.                {2, 6, 5, 1},
  60.                {0, 3, 2, 1},
  61.                {4, 5, 6, 7} },
  62.     norm_vert[6][4] = { {3, 2, 6, 7},
  63.                 {0, 4, 5, 1},
  64.                 {2, 1, 5, 6},
  65.                 {3, 7, 4, 0},
  66.                 {4, 7, 6, 5},
  67.                 {0, 1, 2, 3} },
  68.     texture_coord[4][2] = { {0,0}, {1,0}, {1,1}, {0,1} },
  69.     up[] = {0,0,1}; 
  70.  
  71.  
  72. int    azim = -200, incl, fovy, win_x1, win_x2, win_y1, win_y2, win_w, win_h;
  73. float    dist;
  74.  
  75. float floordata[((GRID)*2)*((GRID)*2)*4*4];
  76.  
  77.  
  78. char    cube[500], floor1[500], floor2[500], back_texture[500];
  79. int    texcube=0, texfloor1=0, texfloor2=0;
  80.  
  81.  
  82. float   matter1[] = { ALPHA, 0.7, LMNULL };
  83. float    empty[] = { LMNULL };
  84.  
  85.  
  86. #ifdef SUBDIV
  87. float    subdiv[] = { PD_MAX_SCREEN_Z, 500.0, 
  88.              PD_MIN_SCREEN_SIZE, 5.0, 
  89.              PD_NULL }; 
  90. #endif SUBDIV
  91.  
  92.  
  93. FILE    *setup;
  94. char    texdir[80];
  95. int    texloc;
  96.  
  97. int fullscreenmode = 0;
  98. int debugmode = 0;
  99.  
  100. docmdline(argc, argv)
  101. int argc;
  102. char **argv;
  103. {
  104.    int opt, err = 0;
  105.    extern char *optarg;
  106.    extern int getopt();
  107.  
  108.    while ((opt = getopt(argc,argv,"Dfs:t:?")) != -1) {
  109.      switch(opt) {
  110.      case 's':
  111.         setup = fopen(optarg, "r");
  112.         if (setup == 0) {
  113.             fprintf(stderr, "blob:  Can't open %s\n", optarg);
  114.             exit(1);
  115.         }
  116.         break;
  117.      case 'D':
  118.         debugmode = 1;
  119.         break;
  120.      case 'f':
  121.         fullscreenmode = 1;
  122.         break;
  123.      case 't':
  124.         strcpy(texdir, optarg);
  125.         texloc = 1;
  126.         break;
  127.      case '?':
  128.      default:
  129.         err++;
  130.         break;
  131.      }
  132.     }
  133.  
  134.     if (setup == 0)
  135.     err++;
  136.  
  137.     if (err) {
  138.     printf("blob -s <setup_file>\n");
  139.     exit(1);
  140.     }
  141. }
  142.  
  143. handledevice(dev, val)
  144. int dev;
  145. short val;
  146. {
  147.     switch(dev) {
  148.     case ESCKEY:
  149.     if (val == 0) {
  150.         gexit();
  151.         exit(0);
  152.     }
  153.     break;
  154.  
  155.     case REDRAW:
  156.           keepaspect(5,4);
  157.       reshapeviewport();
  158.           getsize(&winxsize, &winysize);
  159.       drawscene();
  160.       swapbuffers();
  161.       break;
  162.     default: break;
  163.     }
  164. }
  165.  
  166.  
  167. main(argc, argv) 
  168. int        argc;
  169. char    **argv;
  170. {
  171.     int        v, s, i, j, k, x, y;
  172.     int        tx, ty;
  173.     float   sqrt3;
  174.     char tcube[80], tfloor1[80], tfloor2[80];
  175.     int dev;
  176.     short val;
  177.  
  178.     docmdline(argc, argv);
  179.  
  180.     fscanf(setup, " %i %i %i %i  %s %d %s %d %s %d %s  %f %f %f %f %f %f %f %f %f  %f %i %i %f",
  181.         &win_x1, &win_x2, &win_y1, &win_y2,
  182.         tcube, &texcube, tfloor1, &texfloor1, tfloor2, &texfloor2,
  183.         back_texture,
  184.         &stiff, &damp, &mtime, &mass, &gravity, 
  185.         &floor_damp, &fric, &blur,
  186.         &floor_z, &ceiling_z, &incl, &fovy, &dist);
  187.  
  188.     if (texloc) {
  189.     strcpy(cube,texdir);
  190.     strcat(cube,tcube);
  191.     strcpy(floor1,texdir);
  192.     strcat(floor1,tfloor1);
  193.     strcpy(floor2,texdir);
  194.     strcat(floor2,tfloor2);
  195.     } else {
  196.     strcpy(cube,tcube);
  197.     strcpy(floor1,tfloor1);
  198.     strcpy(floor2,tfloor2);
  199.     }
  200.  
  201.     win_w = win_x2 - win_x1 + 1;
  202.     win_h = win_y2 - win_y1 + 1;
  203.  
  204.     mtime = 1 / mtime;
  205.     gravity *= 9.8;
  206.  
  207.     matter1[1] = blur / 255.0;
  208.  
  209.     for (v = 0; v < VERTICES; v++) {
  210.     for (i = 0; i < 3; i++) {
  211.         vel[v][i] = 0;
  212.     }
  213.     }
  214.  
  215.     sv1[0] = 0;        sv2[0] = 1;        sdist[0] = 1;
  216.     sv1[1] = 1;        sv2[1] = 5;        sdist[1] = 1;
  217.     sv1[2] = 5;        sv2[2] = 4;        sdist[2] = 1;
  218.     sv1[3] = 4;        sv2[3] = 0;        sdist[3] = 1;
  219.     sv1[4] = 3;        sv2[4] = 2;        sdist[4] = 1;
  220.     sv1[5] = 2;        sv2[5] = 6;        sdist[5] = 1;
  221.     sv1[6] = 6;        sv2[6] = 7;        sdist[6] = 1;
  222.     sv1[7] = 7;        sv2[7] = 3;        sdist[7] = 1;
  223.     sv1[8] = 0;        sv2[8] = 3;        sdist[8] = 1;
  224.     sv1[9] = 4;        sv2[9] = 7;        sdist[9] = 1;
  225.     sv1[10] = 5;    sv2[10] = 6;    sdist[10] = 1;
  226.     sv1[11] = 1;    sv2[11] = 2;    sdist[11] = 1;
  227.  
  228.     sv1[12] = 0;    sv2[12] = 5;    sdist[12] = M_SQRT2;
  229.     sv1[13] = 1;    sv2[13] = 4;    sdist[13] = M_SQRT2;
  230.     sv1[14] = 3;    sv2[14] = 6;    sdist[14] = M_SQRT2;
  231.     sv1[15] = 7;    sv2[15] = 2;    sdist[15] = M_SQRT2;
  232.     sv1[16] = 0;    sv2[16] = 7;    sdist[16] = M_SQRT2;
  233.     sv1[17] = 4;    sv2[17] = 3;    sdist[17] = M_SQRT2;
  234.     sv1[18] = 1;    sv2[18] = 6;    sdist[18] = M_SQRT2;
  235.     sv1[19] = 2;    sv2[19] = 5;    sdist[19] = M_SQRT2;
  236.     sv1[20] = 4;    sv2[20] = 6;    sdist[20] = M_SQRT2;
  237.     sv1[21] = 5;    sv2[21] = 7;    sdist[21] = M_SQRT2;
  238.     sv1[22] = 0;    sv2[22] = 2;    sdist[22] = M_SQRT2;
  239.     sv1[23] = 1;    sv2[23] = 3;    sdist[23] = M_SQRT2;
  240.  
  241.     sqrt3 = sqrt(3.0);
  242.     sv1[24] = 0;    sv2[24] = 6;    sdist[24] = sqrt3;
  243.     sv1[25] = 1;    sv2[25] = 7;    sdist[25] = sqrt3;
  244.     sv1[26] = 2;    sv2[26] = 4;    sdist[26] = sqrt3;
  245.     sv1[27] = 3;    sv2[27] = 5;    sdist[27] = sqrt3;
  246.  
  247.     for (s = 0; s < SPRINGS; s++)
  248.     sdist_last[s] = sdist[s];
  249.  
  250.     vert[0][0] = 0.5;
  251.     vert[0][1] = 0.5;
  252.     vert[0][2] = -0.5;
  253.  
  254.     vert[1][0] = -0.5;
  255.     vert[1][1] = 0.5;
  256.     vert[1][2] = -0.5;
  257.  
  258.     vert[2][0] = -0.5;
  259.     vert[2][1] = -0.5;
  260.     vert[2][2] = -0.5;
  261.  
  262.     vert[3][0] = 0.5;
  263.     vert[3][1] = -0.5;
  264.     vert[3][2] = -0.5;
  265.     vert[4][0] = 0.5;
  266.     vert[4][1] = 0.5;
  267.     vert[4][2] = 0.5;
  268.     vert[5][0] = -0.5;
  269.     vert[5][1] = 0.5;
  270.     vert[5][2] = 0.5;
  271.     vert[6][0] = -0.5;
  272.     vert[6][1] = -0.5;
  273.     vert[6][2] = 0.5;
  274.     vert[7][0] = 0.5;
  275.     vert[7][1] = -0.5;
  276.     vert[7][2] = 0.5;
  277.  
  278.     vel[0][0] = 0.05;
  279.     vel[6][0] = -0.05;
  280.  
  281.     for (i = 0; i < VERTICES; i++)
  282.     vert[i][2] += 1.0;
  283.  
  284.     /* create floor data */
  285.     for (i = -GRID, ty=0; i < GRID; i++, ty++) { /* row */
  286.     for (j = -GRID, tx=0; j < GRID; j++, tx++) { /* poly in row */
  287.         for (v=0; v < 4; v++) { /* vert in poly */
  288.         /* compute and enter x,y for current vert */
  289.         floordata[ty*GRIDXSIZE + tx*16 + v*4 +  0] = 
  290.                 ((-GRID + ((texture_coord[v][0]  + tx))) *3.0);
  291.         floordata[ty*GRIDXSIZE + tx*16 + v*4 + 1] = 
  292.                 ((-GRID + ((texture_coord[v][1]  + ty))) *3.0);
  293.         floordata[ty*GRIDXSIZE + tx*16 + v*4 + 2] = (floor_z - 0.01);
  294.         }
  295.     }
  296.     }
  297.  
  298.     if (debugmode)
  299.     foreground(); 
  300.     if (fullscreenmode)
  301.     prefposition(win_x1, win_x2, win_y1, win_y2);
  302.  
  303.     keepaspect(5,4);
  304.     winopen("blob");
  305.  
  306.     glcompat(GLC_OLDPOLYGON, FALSE);
  307.  
  308.     qdevice(ESCKEY);
  309.     qdevice(REDRAW);
  310.  
  311.     doublebuffer(); 
  312.     RGBmode();
  313.     zbuffer(0);
  314.     backface(1);
  315.     gconfig();
  316.     clearscreen();
  317.  
  318.     /* readsource(SRC_BACK); */
  319. /*    zbuffer(TRUE); */
  320.  
  321.     getsize(&winxsize, &winysize);
  322.     mmode(MVIEWING);
  323.     perspective(fovy, (float)winxsize / winxsize, 1, GRID * 12);
  324.     loadmatrix(ident_mat);
  325.  
  326.     lmdef(DEFMATERIAL, 1, 0, matter1);
  327.     lmdef(DEFLMODEL, 1, 0, empty);
  328.     lmdef(DEFLIGHT, 1, 0, empty);
  329.     lmdef(DEFLIGHT, 2, 0, empty);
  330.     lmbind(LMODEL, 1);
  331.     lmbind(LIGHT1, 1);
  332.  
  333. #ifdef STAPUFT
  334.     bind_texture(cube, 1, texcube);
  335.     bind_texture(floor1, 2, texfloor1);
  336.     bind_texture(floor2, 3, texfloor2); 
  337.  
  338.     subpixel(TRUE);
  339. #endif STAPUFT
  340.  
  341.     show_blob();
  342.     swapbuffers();
  343.  
  344.     while(1) {
  345.     while (qtest()) {
  346.         dev = qread(&val);
  347.         handledevice(dev,val);
  348.     }
  349.     drawscene();
  350.     swapbuffers();
  351.     }
  352. }
  353.  
  354. drawscene()
  355. {
  356.         do_gravity();
  357.         do_springs();
  358.         do_move();
  359.         do_floor();
  360.         do_ceiling();
  361.         show_blob();
  362. }
  363.  
  364. show_blob() 
  365. {
  366.     int        i, j, tx, ty;
  367.     int        even = 1;
  368.  
  369. /*    zbuffer(0);
  370.     texbind(TX_TEXTURE_0, 0);
  371.     drawback(back_texture);
  372.     zbuffer(1);
  373.     zclear();*/
  374.  
  375.     cpack(0x00331111);
  376.     clear();
  377.  
  378.     pushmatrix();
  379.     polarview(dist, azim, incl, 0);
  380.     lmbind(LIGHT0, 2);
  381.     azim += 7;
  382.  
  383. #ifdef STAPUFT
  384.  
  385. #ifdef SUBDIVd
  386.     polysubdivide(PD_DEPTH, subdiv);
  387. #endif SUBDIV
  388.  
  389.  
  390.     /* first draw all squares of floor 1 */
  391.     texbind(TX_TEXTURE_0, 2);
  392.     even = 1;
  393.     cpack(Pack(255,255,255,blur));
  394.     for (i = -GRID, ty=0; i < GRID; i++, ty++) {
  395.  
  396.     for (j = (-GRID + even), tx = even; j < GRID; j+=2, tx+=2) {
  397.  
  398.         bgnpolygon();
  399.         t2i(texture_coord[0]);
  400.         v3f(floordata + ty*GRIDXSIZE + tx*16 ); 
  401.  
  402.         t2i(texture_coord[1]);
  403.         v3f(floordata + ty*GRIDXSIZE + tx*16 + 4); 
  404.  
  405.         t2i(texture_coord[2]);
  406.         v3f(floordata + ty*GRIDXSIZE + tx*16 + 8); 
  407.  
  408.         t2i(texture_coord[3]);
  409.         v3f(floordata + ty*GRIDXSIZE + tx*16 + 12); 
  410.  
  411.         endpolygon();
  412.     }
  413.     even ^= 1;
  414.     }
  415.  
  416.     /* then draw all squares of floor 1 */
  417.     even = 0;
  418.     texbind(TX_TEXTURE_0, 3);
  419.     cpack(Pack(255,255,255,blur));
  420.  
  421.     for (i = -GRID, ty=0; i < GRID; i++, ty++) {
  422.     static long    c_toggle = 0, c;
  423.  
  424.     for (j = (-GRID + even), tx = even; j < GRID; j+=2, tx+=2) {
  425.  
  426.         bgnpolygon();
  427.         t2i(texture_coord[0]);
  428.         v3f(floordata + ty*GRIDXSIZE + tx*16 ); 
  429.  
  430.         t2i(texture_coord[1]);
  431.         v3f(floordata + ty*GRIDXSIZE + tx*16 + 4); 
  432.  
  433.         t2i(texture_coord[2]);
  434.         v3f(floordata + ty*GRIDXSIZE + tx*16 + 8); 
  435.  
  436.         t2i(texture_coord[3]);
  437.         v3f(floordata + ty*GRIDXSIZE + tx*16 + 12); 
  438.  
  439.         endpolygon();
  440.     }
  441.     even ^= 1;
  442.     }
  443.  
  444. #ifdef SUBDIV
  445.     polysubdivide(0, 0);
  446. #endif SUBDIV
  447.  
  448. #else STAPUFT
  449.  
  450.     pushmatrix();
  451.     scale(3, 3, 1);
  452.     translate(0, 0, floor_z - 0.01);
  453.     shademodel(FLAT);
  454.     for (i = -10; i < 10; i++) {
  455.     static long    c_toggle = 0;
  456.  
  457.     for (j = -10; j < 10; j++) {
  458.  
  459.         if (c_toggle % 2 == 0) {
  460.         cpack(Pack(255, 80, 80, blur));
  461.         } else {
  462.         cpack(Pack(80,255,80, blur));
  463.         }
  464.  
  465.         c_toggle = 1 - c_toggle;
  466.         rectf(i, j, i+1, j+1);
  467.     }
  468.     c_toggle = 1 - c_toggle;
  469.     }
  470.     popmatrix();
  471.     shademodel(GOURAUD);
  472. #endif STAPUFT
  473.  
  474.     draw_cube();
  475.  
  476.     popmatrix();
  477. }
  478.  
  479.  
  480. #define SHADOWS 5
  481.  
  482. draw_cube() 
  483. {
  484.     float   norm[3];
  485.     int        i, j, k, l;
  486.     static int init = 1;
  487.     static float rndx[5], rndy[5];
  488.  
  489.     if(init) {
  490.         for (l=0; l < 5; l++) {
  491.         rndx[l] = (float)(random() & 0xffff) / 65535 / 50.;
  492.         rndy[l] = (float)(random() & 0xffff) / 65535 / 50.;
  493.     }
  494.         init = 0; 
  495.     }
  496.  
  497.     pushmatrix();
  498.     translate(0,0,floor_z);
  499.     scale(1., 1., 0.);
  500.     texbind(0,0);
  501.     blendfunction(BF_SA, BF_MSA);
  502.     cpack(0x40000000);
  503.     for (l=0; l < 5; l++) {
  504.     translate(rndx[l], rndy[l], 0.);
  505.     for (i = 0; i < 6; i++) {
  506. #ifdef USETMESH
  507.     bgntmesh();
  508.     for (j = 0; j < 4; j++) {
  509.         if(j<2) 
  510.         k = j;
  511.         else
  512.         k = 5-j;
  513.         v2f(vert[face[i][k]]);
  514.     }
  515.     endtmesh();
  516. #else
  517.         bgnpolygon();
  518.         v2f(vert[face[i][0]]);
  519.         v2f(vert[face[i][1]]);
  520.         v2f(vert[face[i][2]]);
  521.         v2f(vert[face[i][3]]);
  522.         endpolygon();
  523. #endif
  524.     }
  525.     }
  526.  
  527.     blendfunction(BF_ONE, BF_ZERO);
  528.     popmatrix();
  529.     zbuffer(TRUE);
  530.     zclear();
  531.  
  532.     lmbind(MATERIAL, 1);
  533.  
  534. #ifdef STAPUFT
  535.     texbind(TX_TEXTURE_0, 1);
  536. #endif STAPUFT
  537.  
  538.     for (i = 0; i < 6; i++) {
  539. #ifdef USETMESH
  540.     bgntmesh();
  541.     for (j = 0; j < 4; j++) {
  542.         if(j<2) 
  543.         k = j;
  544.         else
  545.         k = 5-j;
  546.         vsub(vert[face[i][k]], vert[norm_vert[i][k]], norm);
  547.         vnormal(norm);
  548.         n3f(norm);
  549. #ifdef STAPUFT
  550.         t2i(texture_coord[k]);
  551. #endif STAPUFT 
  552.         v3f(vert[face[i][k]]);
  553.     }
  554.     endtmesh();
  555. #else
  556.     bgnpolygon();
  557.     for (j = 0; j < 4; j++) {
  558.         vsub(vert[face[i][j]], vert[norm_vert[i][j]], norm);
  559.         vnormal(norm);
  560.         n3f(norm);
  561. #ifdef STAPUFT
  562.         t2i(texture_coord[j]);
  563. #endif STAPUFT 
  564.         v3f(vert[face[i][j]]);
  565.     }
  566.     endpolygon();
  567. #endif
  568.     }
  569.     lmbind(MATERIAL, 0);
  570.     zbuffer(FALSE);
  571. }    
  572.  
  573.  
  574.  
  575.  
  576. do_springs() 
  577. {
  578.     int        i;
  579.     float   force_dir[3], damp_dir[3], dist;
  580.  
  581.  
  582.     for (i = 0; i < SPRINGS; i++) {
  583.     vsub(vert[sv2[i]], vert[sv1[i]], force_dir);
  584.     vcopy(force_dir, damp_dir);
  585.     dist = vlength(force_dir);
  586.     
  587.     vscale(force_dir, (dist - sdist[i]) * stiff);
  588.  
  589.     vadd(force_dir, tot_force[sv1[i]], tot_force[sv1[i]]);
  590.     vsub(tot_force[sv2[i]], force_dir, tot_force[sv2[i]]);
  591.  
  592.     vscale(damp_dir, damp * (dist - sdist_last[i]) * mass);
  593.     vadd(tot_force[sv1[i]], damp_dir, tot_force[sv1[i]]);
  594.     vsub(tot_force[sv2[i]], damp_dir, tot_force[sv2[i]]);
  595.  
  596. /* debug
  597.     if (vlength(damp_dir) > fabs(dist - sdist_last[i]) * mass)
  598.         printf("Damping too big, or mtime step too small\n");
  599. */
  600.  
  601.     sdist_last[i] = dist;
  602.     }
  603. }
  604.  
  605.  
  606. do_move() 
  607. {
  608.     int        i;
  609.  
  610.     for (i = 0; i < VERTICES; i++) {
  611.     vscale(tot_force[i], mtime * (1/30.0) / mass);
  612.  
  613.     vadd(tot_force[i], vel[i], vel[i]);
  614.     vadd(vert[i], vel[i], vert[i]);
  615.     }
  616. }
  617.  
  618.  
  619. do_gravity() 
  620. {
  621.     int        i;
  622.  
  623.     for (i = 0; i < VERTICES; i++) {
  624.     vset(tot_force[i], 0.0, 0.0, -gravity * mass);
  625.     }
  626. }
  627.  
  628.  
  629. do_floor() 
  630. {
  631.     int        i;
  632.  
  633.     for (i = 0; i < VERTICES; i++) {
  634.     if (vert[i][2] < floor_z) {
  635.         vert[i][2] = floor_z;
  636.         vel[i][2] = -vel[i][2] * (1 + floor_damp);
  637.     }
  638.     }
  639. }
  640.  
  641. do_ceiling() 
  642. {
  643.     int        i, j;
  644.  
  645.     for (i = 0; i < VERTICES; i++) {
  646.     if (vert[i][2] > ceiling_z) {
  647.         vert[i][2] = ceiling_z;
  648.         for (j = 0; j < VERTICES; j++) {
  649.         vel[j][2] = 0;
  650.         }
  651.     }
  652.     }
  653. }
  654.  
  655. clearscreen()
  656. {
  657.     cpack(0x00808080);
  658.     clear();
  659.     swapbuffers();
  660. }
  661.